//__________________________________________________________________
//
//  Module      :   ASYN_FIFO
//              
//  By          :   Kejie
//  E-mail      :   Kejie1208@126.com
//  Created     :   08/12/10 
//  Read Mode   :   First-Word Fall-Through
//                  All Outputs are Registed
//  First-Word
//  Fall-Through
//  Notes:          The First Word into the fifo will be valid in the w_data,
//                  while the r_empty is fall down.
//                  And if r_re is assigned some time, 
//                  then in the next Cycle 
//                  the w_data will be the Second Word  
//___________________________________________________________________

`timescale 1ns/1ns

module  enqueue_result_fifo_fwft #(  
parameter   L=7,        //Fifo Depth = 2^L+2;
parameter   DW=1      //Data Width = DW;
)
(
  
  input  wire               clk,
  input  wire               clr,
  input  wire  [9:0]        ram_2p_cfg_register,                      
  input  wire               w_data,
  input  wire               w_we,
  output wire               w_full,
  output wire               w_afull,
                        
  output wire               r_data,
  input  wire               r_re,
  output wire               r_empty,
  output wire               r_aempty
);

wire            rst_n         ;
wire [L-1:0]    ram_rd_addr   ;
wire [L-1:0]    ram_wr_addr   ;
wire [L-1:0]    ram_rd_addr_DL;
wire            ram_we_n      ;
wire [  2:0]    ram_data_no_use;
wire 		empty 		;
reg		empty_dl 	;

assign rst_n = clr;

    DW_fifoctl_s1_sf #(
      .depth(128), 
      .ae_level(1), 
      .af_level(1), 
      .err_mode(0), 
      .rst_mode(0)) 
    FIFO_CTL(
      .clk(clk),
      .rst_n(rst_n),
      .push_req_n(~w_we),
      .pop_req_n(~r_re),
      .diag_n(1'b1),
      .empty(empty),
      .almost_empty(r_aempty),
      .half_full(),
      .almost_full(w_afull),
      .full(w_full),
      .error(),
      .we_n(ram_we_n),
      .wr_addr(ram_wr_addr),
      .rd_addr(ram_rd_addr)
      );
assign ram_rd_addr_DL = (r_re) ? ram_rd_addr + 'd1 : ram_rd_addr;


tp_rf_2p_d128_w4 U_tp_rf_2p_d128_w4(
  .clk   (clk),              
  .rst_n (rst_n),
  .wen   (~ram_we_n),              //active-HIGH
  .waddr (ram_wr_addr),
  .wdata ({3'b0,w_data}),
  .ren   (1'b1),              //active-HIGH
  .raddr (ram_rd_addr_DL),
  .rdata ({ram_data_no_use,r_data})
  );
//ram_2p_d128_w4_wrapper U_ram_2p_d128_w4_wrapper (
//	.clk(clk),
//    .ram_2p_cfg_register(ram_2p_cfg_register),
//	.wren(~ram_we_n),
//	.waddr(ram_wr_addr),
//	.wdata({3'b0,w_data}),
//	.rden(1'b1),
//	.raddr(ram_rd_addr_DL),
//	.rdata({ram_data_no_use,r_data})
//	);

always @(posedge clk or negedge clr) begin
  if (~clr) begin
    // reset
    empty_dl <= 1'b1;
  end
  else if(r_aempty & w_we & r_re) begin
    empty_dl <= 1'b1;	
  end
  else begin
    empty_dl <= empty;
  end
end

assign r_empty = empty_dl | empty;

endmodule  
